<?php

namespace app\admin\service\auth;

class RuleParser
{



    /**
     * Undocumented function
     *
     * @param [type] $rule
     * @return Rule|null
     */
    function ruleParse($rule)
    {
        $tokens =  explode('/',$rule);
        $rules = [

        ];
        foreach($tokens as $key=>$token){
            if(strlen($token) < 1){
                return null;
            }
            switch($token[0]){
                case '*':
                    if($token == '**'){
                        if($key !== count($tokens) -1){
                            return null;
                        }else{
                            $rules[] = [
                                'type'=>'**',
                                'value'=>'**'
                            ];
                        }
                    }else{
                        $rules[] = [
                            'type'=>'*',
                            'value'=>'*'
                        ];
                    }
                break;
                case '[':
                    $values = [];
                    if(preg_match('/^\[([^\]]+)\]$/',trim($token),$match)){
                        $values = array_map(function($item){
                            return trim($item);
                        },explode(',',$match[1]));
                    }else{
                        return null;
                    }
                    $rules[] = [
                        'type'=>'enum',
                        'value'=>$values
                    ];
                break;
                case '{':
                    $values = [];
                    if(preg_match('/^\{(\s*\d+\s*\,\s*\d+\s*)\}$/',trim($token),$match)){
                        $values = array_map(function($item){
                            return (int)trim($item);
                        },explode(',',$match[1]));
                    }else{
                        return null;
                    }
                    if($values[0] >= $values[1]){
                        return null;
                    }
                    $rules[] = [
                        'type'=>'between',
                        'value'=>$values 
                    ];
                break;
                case '$':
                    $rules[] = [
                        'type'=>'$',
                        'value'=>'$'
                    ]; 
                break;
                default:
                    if(preg_match('/^[A-Za-z0-9_\-]+$/',trim($token),$match)){
                        $rules[] = [
                            'type'=>'const',
                            'value'=>$token
                        ]; 
                    }else{
                        return null;
                    }
            }
        }
        return new Rule($rules);
    }

    function verifyRule($rule)
    {
        return $this->ruleParse($rule) !== null;
    }

    function buildRule($rules)
    {
        $tokens = [];
        foreach($rules as $rule){
            switch($rule['type']){
                case 'enum':
                    $value = implode(',',$rule['value']);
                    $tokens[] = '{'.$value.'}';
                break;
                case 'between':
                    $value = implode(',',$rule['value']);
                    $tokens[] = '['.$value.']';
                break;
                default:
                    $token[] = $rule['value'];
            }
        }
        return explode('/',$tokens);
    }
}